`include "ascon_define.v"

module `P6_8
(
     input                                       clk_i,
     input                                       rst_n_i,

     input                                       p6_8_en_i,
     input                                       p6_8_mode_i,                   //0:为128a模式 1：为128模式
     input                                       p6_8_vld_i,
     input                            [`S_W-1:0] p6_8_s_i,

     output                           [`S_W-1:0] p6_8_s_o,
     output                                      p6_8_vld_o
);

wire                              [`PC_CR_W-1:0] r_cr_i [8-1:0];
wire                                  [`S_W-1:0] r_s_i [8-1:0];
wire                                  [`S_W-1:0] r_s_o [8-1:0];
reg                                   [`S_W-1:0] r_s_r [8-1:0];

wire                                             p6_vld_w;
wire                                             p8_vld_w;

wire                                             p6_en_w;
wire                                             p8_en_w;

wire                                     [6-1:0] p6_vld_en_w;
wire                                     [8-1:0] p8_vld_en_w;

assign p6_8_s_o         = (p6_8_mode_i == 1'b0) ? r_s_r[7] : r_s_r[5];
assign p6_8_vld_o       = (p6_8_mode_i == 1'b0) ? p8_vld_w : p6_vld_w;

assign p6_en_w          = (p6_8_mode_i == 1'b0) ? 1'b0 : p6_8_en_i;
assign p8_en_w          = (p6_8_mode_i == 1'b0) ? p6_8_en_i : 1'b0;

assign r_cr_i[0]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'hb4 : `PC_CR_W'h96;
assign r_cr_i[1]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'ha5 : `PC_CR_W'h87;
assign r_cr_i[2]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'h96 : `PC_CR_W'h78;
assign r_cr_i[3]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'h87 : `PC_CR_W'h69;
assign r_cr_i[4]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'h78 : `PC_CR_W'h5a;
assign r_cr_i[5]        = (p6_8_mode_i == 1'b0) ? `PC_CR_W'h69 : `PC_CR_W'h4b;
assign r_cr_i[6]        = `PC_CR_W'h5a;
assign r_cr_i[7]        = `PC_CR_W'h4b;

//数据有效信号打拍 ascon-128a模式
`SINGLE_BIT_ANY_CYC
    #(
     .CYC_N                            (8                                      )
     )
u_singla_bit_8_cyc
     (
     .clk_i                            (clk_i                                  ),
     .rst_n_i                          (rst_n_i                                ),
     .en_i                             (p8_en_w                                ),
     .dat_d_i                          (p6_8_vld_i                             ),
     .dat_q_o                          (p8_vld_w                               ),
     .vld_o                            (p8_vld_en_w                            )
     );
//数据有效信号打拍 ascon-128模式
`SINGLE_BIT_ANY_CYC
    #(
     .CYC_N                            (6                                      )
     )
u_singla_bit_6_cyc
     (
     .clk_i                            (clk_i                                  ),
     .rst_n_i                          (rst_n_i                                ),
     .en_i                             (p6_en_w                                ),
     .dat_d_i                          (p6_8_vld_i                             ),
     .dat_q_o                          (p6_vld_w                               ),
     .vld_o                            (p6_vld_en_w                            )
     );

genvar index;

generate
for (index = 0;index < 8; index = index + 1)
begin :U_P68_ROUND_LOOP

`ROUND
u_round
(
     .cr_i                             (r_cr_i[index]                          ),
     .s_i                              (r_s_i[index]                           ),
     .s_o                              (r_s_o[index]                           )
);

if (index == 0)

assign r_s_i[0]         = p6_8_s_i;

else

assign r_s_i[index]     = r_s_r[index-1];

if (index <6)

always @(posedge clk_i or negedge rst_n_i)
begin : R_S_R_PROG
  if (rst_n_i == 1'b0)
    r_s_r[index]        <= {`S_W{1'b0}};
  else if ((p6_8_en_i == 1'b1)&&((p6_vld_en_w[index] == 1'b1)||(p8_vld_en_w[index] == 1'b1)))
    r_s_r[index]        <= r_s_o[index];
  else
    r_s_r[index]        <= r_s_r[index];
end

else

always @(posedge clk_i or negedge rst_n_i)
begin : R_S_R_PROG
  if (rst_n_i == 1'b0)
    r_s_r[index]        <= {`S_W{1'b0}};
  else if ((p6_8_en_i == 1'b1)&&(p8_vld_en_w[index] == 1'b1))
    r_s_r[index]        <= r_s_o[index];
  else
    r_s_r[index]        <= r_s_r[index];
end

end

endgenerate
endmodule